using System;
using System.Collections.Generic;
using System.Windows.Media;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Color = Microsoft.Xna.Framework.Color;
using Matrix = Microsoft.Xna.Framework.Matrix;

using GoblinXNA;
using GoblinXNA.Graphics;
using GoblinXNA.SceneGraph;
using Model = GoblinXNA.Graphics.Model;
using GoblinXNA.Graphics.Geometry;
using GoblinXNA.Device.Generic;
using GoblinXNA.Device.Capture;
using GoblinXNA.Device.Vision;
using GoblinXNA.Device.Vision.Marker;
using GoblinXNA.Device.Util;
using GoblinXNA.Physics;
using GoblinXNA.Helpers;
using GoblinXNA.Shaders;
using GoblinXNA.UI;
using GoblinXNA.UI.UI2D;
using GoblinXNA.Physics.Matali;
using Komires.MataliPhysics;
using MataliPhysicsObject = Komires.MataliPhysics.PhysicsObject;
using GoblinXNA.UI.UI3D;
using GoblinXNA.Sounds;
//using Nuclex.Fonts;

namespace SplashOn_PhoneLib
{
    class SplashOn_Shooting
    {
        Color[] shootingPowerBarColors;
        Color[] splashingPowerBarColors;
        SoundEffect bounceSound;
        SoundEffect splashSound;
        volatile bool doneHoldingsplashing = false;
        volatile bool doneHoldingshooting = false;
        int shooterId = 0;
        int currentIndex =0;
        TransformNode groundNode;
        Microsoft.Xna.Framework.Color sc;
        GeometryNode shootSphere; 

        public SplashOn_Shooting()
        {
            splashingPowerBarColors = new Color[7];
            shootingPowerBarColors = new Color[7];

            resetPowerBar(splashingPowerBarColors);
            resetPowerBar(shootingPowerBarColors);
        }

        public void ShootSphere(Vector3 near, Vector3 far, Microsoft.Xna.Framework.Color selectedColor, TransformNode gNode, SoundEffect bounce, SoundEffect splash)
        {
            this.groundNode = gNode;
            doneHoldingsplashing = true;
            bounceSound = bounce;
            sc = selectedColor;
            splashSound = splash;

            SoundEffectInstance instance = Sound.Instance.PlaySoundEffect(bounceSound);
            Material shooterMat = new Material();
            if (selectedColor.A == 0 && selectedColor.R == 0 && selectedColor.G == 0 && selectedColor.B == 0)
            {
                shooterMat.Diffuse = Color.Purple.ToVector4();
                shooterMat.Specular = Color.Yellow.ToVector4();
            }
            else
            {
                shooterMat.Diffuse = new Vector4(selectedColor.R / 255f, selectedColor.G / 255f, selectedColor.B / 255f, selectedColor.A / 255f);
                shooterMat.Specular = Color.Yellow.ToVector4();
            }

            shooterMat.Specular = Color.Yellow.ToVector4();
            shooterMat.SpecularPower = 10;
            shootSphere = new GeometryNode("ShooterSphere" + shooterId++);
            shootSphere.Model = new Sphere(15f, 20, 20);
            shootSphere.Material = shooterMat;
            shootSphere.Physics = new MataliObject(shootSphere);
            ((MataliObject)shootSphere.Physics).CollisionStartCallback = sphereCollideWithGround;
            shootSphere.Physics.Interactable = true;
            shootSphere.Physics.Collidable = true;
            shootSphere.Physics.Shape = GoblinXNA.Physics.ShapeType.Sphere;
            shootSphere.Physics.Mass = 60f;
            shootSphere.AddToPhysicsEngine = true;

            // Calculate the direction to shoot the box based on the near and far point
            Vector3 linVel = far - near;
            linVel.Normalize();
            // Multiply the direction with the velocity of 600
            linVel *= 200f * currentIndex;

            // Assign the initial velocity to this shooting box
            shootSphere.Physics.InitialLinearVelocity = linVel;

            TransformNode shooterTrans = new TransformNode();
            shooterTrans.Translation = near;

            groundNode.AddChild(shooterTrans);
            shooterTrans.AddChild(shootSphere);
            resetPowerBar(splashingPowerBarColors);
        }

        public void ShootObject(Vector3 near, Vector3 far, TransformNode gNode, SoundEffect bounce, SoundEffect splash)
        {
            this.groundNode = gNode;
            doneHoldingshooting = true;
            bounceSound = bounce;
            splashSound = splash;

            SoundEffectInstance instance = Sound.Instance.PlaySoundEffect(bounceSound);

            GeometryNode selectedObjectNode = new GeometryNode();
            if (Objects.selectedObjectGeometryNode == null || Objects.selectedObjectGeometryNode.Name == "Torus")
            {
                selectedObjectNode.Model = new Torus(0.5f, 1.2f, 30, 30);
                Material torusMat = new Material();
                torusMat.Diffuse = Color.Yellow.ToVector4();
                torusMat.Specular = Color.White.ToVector4();
                torusMat.SpecularPower = 10;
                selectedObjectNode.Material = torusMat;
            }
            else if (Objects.selectedObjectGeometryNode.Name == "Cone")
            {
                selectedObjectNode.Model = new Cylinder(1.5f, 0, 3f, 20);
                Material coneMat = new Material();
                coneMat.Diffuse = Color.Cyan.ToVector4();
                coneMat.Specular = Color.White.ToVector4();
                coneMat.SpecularPower = 5;
                selectedObjectNode.Material = coneMat;
            }
            else if (Objects.selectedObjectGeometryNode.Name == "Cylinder")
            {
                selectedObjectNode.Model = new Cylinder(1.5f, 1.5f, 3f, 20);
                Material coneMat = new Material();
                coneMat.Diffuse = Color.SeaGreen.ToVector4();
                coneMat.Specular = Color.White.ToVector4();
                coneMat.SpecularPower = 5;
                selectedObjectNode.Material = coneMat;

         /*       ModelLoader loader = new ModelLoader();
                IModel splashBlobModel = loader.Load("", "p1_wedge");
                ((GoblinXNA.Graphics.Model)splashBlobModel).UseInternalMaterials = true;
                selectedObjectNode.Model = splashBlobModel; */
            }

          //  selectedObjectNode.Material = Objects.selectedObjectGeometryNode.Material;

           // selectedObjectNode = Objects.selectedObjectGeometryNode;
            selectedObjectNode.Physics = new MataliObject(selectedObjectNode);
            ((MataliObject)selectedObjectNode.Physics).CollisionStartCallback = objectCollideWithGround;
            selectedObjectNode.Physics.Interactable = true;
            selectedObjectNode.Physics.Collidable = true;
            selectedObjectNode.Physics.Shape = GoblinXNA.Physics.ShapeType.Sphere;
            selectedObjectNode.Physics.Mass = 60f;
            selectedObjectNode.AddToPhysicsEngine = true;

            // Calculate the direction to shoot the box based on the near and far point
            Vector3 linVel = far - near;
            linVel.Normalize();
            // Multiply the direction with the velocity of 600
            linVel *= 200f * currentIndex;

            // Assign the initial velocity to this shooting box
            selectedObjectNode.Physics.InitialLinearVelocity = linVel;

            TransformNode shooterTrans = new TransformNode();
            shooterTrans.Translation = near;

            TransformNode trans = new TransformNode();
            trans.Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, MathHelper.ToRadians(90));
            if (Objects.selectedObjectTransformNode == null)
                trans.Scale = new Vector3(10);
            else
            {
                trans.Translation = Objects.selectedObjectTransformNode.Translation;
                trans.Scale = 2 * Objects.selectedObjectTransformNode.Scale;
                trans.Rotation *= Objects.selectedObjectTransformNode.Rotation;
            }
            groundNode.AddChild(shooterTrans);
            shooterTrans.AddChild(trans);
            trans.AddChild(selectedObjectNode);
            resetPowerBar(shootingPowerBarColors);
        }

        private void sphereCollideWithGround(MataliPhysicsObject baseObject, MataliPhysicsObject collidingObject)
        {
            DebugHelper.w("sphereCollideWithGround");            

            String materialName = ((IPhysicsObject)collidingObject.UserTagObj).MaterialName;
            shootSphere.Material.Diffuse = new Vector4(1, 1, 1, 0);

            baseObject.EnableMoving = false;
            if (materialName.Equals("Canvas") || materialName.Equals("Cone") || materialName.Equals("Torus") || materialName.Equals("Cylinder") || materialName.Equals("Splash"))
            {
                //Komires.MataliPhysics.Transform ts = collidingObject.InitLocalTransform;
                //SplashHelper.createSplashBloabAt(groundNode, ((IPhysicsObject)baseObject.UserTagObj).PhysicsWorldTransform.Translation, sc);
                //SoundEffectInstance instance = Sound.Instance.PlaySoundEffect(splashSound);
                ModelLoader loader = new ModelLoader();
                Random r = new Random();
                int random = r.Next(4) % 2; 
                String blobFilename = "blob1";
                if (random == 0)
                    blobFilename = "blob3";          
                IModel splashBlobModel = loader.Load("", blobFilename);    

                Vector3 position = ((IPhysicsObject)baseObject.UserTagObj).PhysicsWorldTransform.Translation;
                position.Z = 6;
                TransformNode splashBlobTransformNode = new TransformNode()
                {
                    Translation = position,
                    Scale = new Vector3(AppConstants.DEFAULT_BLOB_SCALE),
                    Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitX, MathHelper.ToRadians(90))
                };

                if (sc.A == 0 && sc.R == 0 && sc.G == 0 && sc.B == 0)
                {
                    sc = Color.Purple;
                }

                GeometryNode cloneNode = new GeometryNode()
                {
                    Model = splashBlobModel,
                    Material = new Material
                    {                     
                        Ambient = sc.ToVector4(),
                        Diffuse = sc.ToVector4(),
                        Emissive = sc.ToVector4(),
                        Specular = sc.ToVector4(),
                        SpecularPower = 10,
                    },
                };

                cloneNode.Physics.MaterialName = "Splash";
                splashBlobTransformNode.AddChild(cloneNode);
                groundNode.AddChild(splashBlobTransformNode);

                Notifier.AddMessage("Contact with ground");
            }

            baseObject.RemoveAllPhysicsObjects();
        }

        private void objectCollideWithGround(MataliPhysicsObject baseObject, MataliPhysicsObject collidingObject)
        {
            baseObject.Material.SetDiffuse(Color.Red.ToVector3());
            //(IPhysicsObject)baseObject).Material = new Material();
            //new Vector4(1f, 1f, 0f, 1f); 
            baseObject.EnableMoving = false;
            String materialName = ((IPhysicsObject)collidingObject.UserTagObj).MaterialName;
            if (materialName.Equals("Canvas"))
            {
                Notifier.AddMessage("Contact with ground");
            }
            else
            {
                
            }
        }

        public void generateSplashingPowerBar()
        {
            int initialTicks = System.Environment.TickCount;
            doneHoldingsplashing = false;
            currentIndex = 0;

            while (!doneHoldingsplashing)
            {                
                for (int i = 0; i < 7; i++)
                {
                    if (System.Environment.TickCount > initialTicks + i * 200)
                    {
                        if (i == 6)
                            Console.WriteLine("");
                        splashingPowerBarColors[i] = new Color(1f, (6 - i) / 7f, 0f);
                        currentIndex = i;
                    }
                }
            }
        }

        public void generateShootingPowerBar()
        {
            int initialTicks = System.Environment.TickCount;
            doneHoldingshooting = false;
            currentIndex = 0;

            while (!doneHoldingshooting)
            {                
                for (int i = 0; i < 7; i++)
                {
                    if (System.Environment.TickCount > initialTicks + i * 200)
                    {
                        shootingPowerBarColors[i] = new Color(1f, (6 - i) / 7f, 0f);
                        currentIndex = i;
                    }
                }
            }
        }

        public Color[] getShootingBarColors()
        {
            return shootingPowerBarColors;
        }

        public Color[] getSplashingBarColors()
        {
            return splashingPowerBarColors;
        }

        public void resetPowerBar(Color[] powerbar)
        {
            for (int i = 0; i < 7; i++)
            {
                powerbar[i] = Color.Transparent;
            }
        }
    }
}
